home *** CD-ROM | disk | FTP | other *** search
- #import "myMainObject.h"
- #import <appkit/ScrollView.h>
- #import <streams/streams.h>
- #import <utmp.h>
- #import <libc.h>
- #import <sys/param.h>
- #import <dpsclient/dpsNeXT.h>
-
- extern id infoManager;
- int find();
- void enter();
- void clear_marks();
- void remove_unmarked();
-
- /*===========================================================================
-
- File: myMainObject.m
- Purpose: This file replaces the file "myApp.m" in the previous
- version. 3.0 doesn't like sub-classes of NXApp.
- This object does the work for determining who is on-line.
- This object receives the appDidInit method signals other
- objects that this event occured.
-
- NOTE: All areas of code which deal with the TextToSpeech Kit have
- been put under conditional compilation. If you do not
- have the TextToSpeech kit, simply comment out the flags
- in the Makefile.preamble file and this code should compile
- for you.
-
- ===========================================================================*/
-
-
- @implementation myMainObject
-
- void who(DPSTimedEntry teNumber, double now, char *userData)
-
- /* Call this function via the DPS Timed Entry */
-
- {
- struct utmp temp; /* Utmp structure. See utmp.h */
- char tempHost[MAXHOSTNAMELEN];
-
- clear_marks(); /* Clear marked */
- utmpFile = NXMapFile("/etc/utmp", NX_READONLY); /* Map utmp file into memory */
- if (utmpFile == NULL)
- {
- exit(0);
- }
- while( NXRead(utmpFile, &temp, sizeof(struct utmp)) !=0 ) /* Read next entry */
- {
- if (temp.ut_name[0] != '\000') /* Is is a real user? */
- {
- if (strlen(temp.ut_host)==0)
- {
- gethostname(tempHost, MAXHOSTNAMELEN);
- enter(temp.ut_line, temp.ut_name, tempHost); /* Yes, enter or affirm in list */
- }
- else
- enter(temp.ut_line, temp.ut_name, temp.ut_host); /* Yes, enter or affirm in list */
- }
- }
- remove_unmarked(); /* Remove all un-referenced entries in
- the list */
-
- NXClose(utmpFile); /* Close utmp file */
- }
-
- -appDidInit:sender
- {
- #ifdef SPEECH
- const char *appPath;
- char dictPath[256];
- #endif
- /* Init Icon Position coordinates */
- nextX = nextY = 0;
-
- /* Initialize List pointers */
- last = users = NULL;
-
- /* Fudge. C calls seem to need this */
- c_self = self;
-
- DPSAddTimedEntry((double)5.0, (DPSTimedEntryProc) who, NULL, NX_BASETHRESHOLD);
- infoManager = localInfoMgr;
-
- /* Read in Defaults */
- [infoManager initDefaults];
-
- #ifdef SPEECH
- /* Get application directory and set up TTS Kit application dictionary */
- appPath = [self appDirectory];
- strcpy(dictPath, appPath);
- strcat(dictPath, "/WhosOnFirst.preditor");
-
- /* Initialize the speech. Include the application dictionary.*/
- [infoManager initSpeech:dictPath];
- #endif
-
- return(self);
- }
-
- /*===========================================================================
-
- Method: appDirectory
- Purpose: To determine the current working directory of this
- application. The TextToSpeech application dictionary is
- located within WhosOnFirst.app. To install this dictionary
- into the search path of the TextToSpeech Kit, we must provide
- the speech server with the full path.
-
- ===========================================================================*/
-
- -(const char *) appDirectory
- {
- static char appDirectory[256];
- FILE *process;
- char command[256];
- char *suffix;
-
- strcpy(appDirectory, NXArgv[0]);
- if (appDirectory[0] == '/')
- { /* if absolute path */
- if (suffix = rindex(appDirectory, '/'))
- *suffix = '\000'; /* remove executable name */
- }
- else
- {
- sprintf(command, "which '%s'\n", NXArgv[0]);
- process = popen(command, "r");
- fscanf(process, "%s", appDirectory);
- pclose(process);
- if (suffix = rindex(appDirectory, '/'))
- *suffix = '\000'; /* remove executable name */
- chdir(appDirectory);
- getwd(appDirectory);
- }
- return ( (const char *) appDirectory);
- }
-
- /*===========================================================================
-
- Method: newIconUser: name
- tty: ttystr
- host: hoststr
- xcoord: x
- ycoord: y
-
- Purpose: When a new user is detected, this method creats an icon
- for him/her and puts the utmp information within its own
- database.
-
- ===========================================================================*/
-
- -newIconUser: (const char *)name tty: (const char *)ttystr host: (const char *) hoststr xcoord: (float)x ycoord: (float)y
- {
- NXRect windowRect;
-
-
- #ifdef SPEECH
- /* Tell infoManager to Speak */
- [infoManager speakLoginMessage: name tty:ttystr host:hoststr];
- #endif
-
- iconWindow = [Window alloc]; /* Get a window instance */
-
- /* Calulate Screen Coordinates */
- windowRect.origin.x = 4.0 + 64.0 * x;
- windowRect.origin.y = 0.0 + 64.0 * y;
- windowRect.size.height = windowRect.size.width = 64.0; /* Icon size 64x64 */
-
- /*Init the window content */
- [iconWindow initContent: &windowRect style: NX_PLAINSTYLE
- backing: NX_BUFFERED buttonMask:0 defer: YES];
-
- /* Get an IconView Instance */
- icon = [[IconView alloc] init];
-
- /* Set IconView as the window's contentView */
- [[iconWindow setContentView: icon] free];
-
- [iconWindow setDelegate:icon]; /* Make view the window's delegate */
- [iconWindow makeFirstResponder:icon]; /* and first responder */
-
- [iconWindow addToEventMask:NX_MOUSEDOWNMASK];
-
- /* Add to window list */
- [iconWindow makeKeyAndOrderFront:self];
-
- [icon iconSetName: name]; /* Set icon variables */
- [icon iconSetTty: ttystr];
- [icon iconSetHostName: hoststr];
-
- return iconWindow;
- }
-
- /*===========================================================================
-
- Method: terminate:sender
-
- Purpose: The terminate method is sent here. This object notifies
- other objects that the program is about to terminate
-
- ===========================================================================*/
-
- - terminate:sender
- {
- [infoManager cleanUp];
- [owner terminate:sender];
- return self;
- }
-
- /*===========================================================================
-
- Function: enter (tty, name, hostname)
-
- Purpose: When a new user is detected, information about his/her
- tty, login name, and hostname are kept in a small database.
- This function enters the user information into the
- data structures.
-
- Structure: The data base is a simple linked-list.
-
- ===========================================================================*/
-
- void enter(tty,name, hostname)
- char *tty, *name, *hostname;
- {
- struct record *temp;
-
-
- if (find(tty, name)==0) /* If new entry, malloc space and put in list */
- {
- temp = (struct record *) malloc(sizeof (struct record ));
- temp->next = NULL;
-
- /* New Icon */
- temp->windowPointer = [c_self newIconUser: name tty: tty host: hostname
- xcoord: (float)nextX ycoord:(float) nextY];
-
- temp->x = (float)nextX; /* Position Icon in "dock" */
- temp->y = (float)nextY;
- temp->marked = 1; /* Mark icon as referenced */
-
- strcpy(temp->name, name); /* User name */
- temp->name[8] = '\000';
- strcpy(temp->tty, tty); /* TTY name */
- strcpy(temp->hostname, hostname); /* Hostname */
-
- if (last == NULL) /* First entry in list (usually console) */
- {
- users = temp;
- last = temp;
- }
- else /* Not first entry in list */
- {
- last->next = temp;
- last = temp;
- }
-
- nextY++; /* Update coordinate for next icon */
- if (nextY>=12)
- {
- nextY = 0;
- nextX++;
- }
- }
- }
-
- void clear_marks() /* Simply traverse list and clear "marked" item in struct */
- {
- struct record *temp;
-
- temp = users;
- while (temp!=NULL)
- {
- temp->marked = 0;
- temp = temp->next;
- }
- }
-
- void remove_unmarked() /* Remove all items from the list which have not been referenced */
- {
- struct record *temp,*prev;
-
- nextX = nextY = 0;
- temp = users;
- prev = temp;
- while (temp!=NULL)
- {
- if (temp->marked == 0) /* Standard linked list removal algorithm */
- {
-
- #ifdef SPEECH
- [infoManager speakLogoutMessage: temp->name tty:temp->tty host:temp->hostname];
- #endif
- if (temp == users) /* Remove head item */
- {
- users = temp->next;
- [temp->windowPointer free];
- free(temp);
- temp = users->next;
- }
- if (temp == last) /* Remove last item */
- {
- last = prev;
- prev -> next = NULL;
- [temp->windowPointer free];
- free(temp);
- temp = NULL;
- }
- else /* Remove internal item */
- {
- prev->next = temp->next;
- [temp->windowPointer free];
- free(temp);
- temp = prev->next;
- }
- }
- else
- {
- temp->x = 4.0 + 64.0 * (float) nextX; /* Calulate Screen Coordinates */
- temp->y = 0.0 + 64.0 * (float) nextY;
-
- /* Reposition icon to new location */
- [temp->windowPointer moveTo: temp->x : temp->y];
- [[temp->windowPointer contentView] display];
-
- nextY++; /* Calculate next icon position */
- if (nextY>=12)
- {
- nextY = 0;
- nextX++;
- }
- prev = temp;
- temp = temp->next;
- }
- }
- }
-
- int find(tty,name) /* Return a 1 if record with "name" and "tty" exists in the list */
- /* Mark record as referenced so that it is not removed from the list */
- char *tty,*name;
- {
- struct record *temp;
-
- temp = users; /* Head of list */
- while(temp!=NULL)
- {
- if ((strncmp(temp->tty, tty,8)==0)&&(strncmp(temp->name,name,8) ==0))
- {
- temp->marked = 1;
- return(1);
- }
- temp = temp->next;
- }
- return(0);
- }
-
- @end
-